/*
 * Copyright 2007 Matt Jensen
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */
package org.jtell.config;

import java.util.Map;
import java.util.Set;

/**
 * <p>
 * <code>EventSinkMetadata</code> defines the public interface to an object which describes an application event sink.
 * An event sink is typically a method on an application class which is to be invoked to handle events of specific
 * types.
 * </p>
 * <p>
 * Implementors of this interface must implement {@link #equals(Object)} and {@link #hashCode()} such that two instances
 * which refer to the same application event sink, order information, attributes, and contributions are themselves
 * considered equal. 
 * </p>
 */
public interface EventSinkMetadata
{
    /**
     * <p>
     * Get metadata describing the tokens <em>after</em> whose contribution the described event sink should be invoked.
     * </p>
     *
     * @return {@link Set} of {@link OrderMetadata} instances.
     */
    Set<OrderMetadata> getAfterOrders();

    /**
     * <p>
     * Get additional event matching attributes.
     * </p>
     *
     * @return {@link Map} of attribute keys and values.
     */
    Map<String, String> getAttributes();

    /**
     * <p>
     * Get metadata describing the tokens <em>before</em> whose contribution the described event sink should be invoked.
     * </p>
     *
     * @return {@link Set} of {@link OrderMetadata} instances.
     */
    Set<OrderMetadata> getBeforeOrders();

    /**
     * <p>
     * Get the contributions provided by the invocation of the described event sink.
     * </p>
     *
     * @return {@link Set} of {@link String} instances.
     */
    Set<String> getContributions();

    /**
     * <p>
     * Get the fully qualified name of the supported event class.
     * </p>
     *
     * @return {@link String} fully qualified class name.
     */
    String getEventClassName();

    /**
     * <p>
     * Get the fully qualified name of the listener class.
     * </p>
     *
     * @return {@link String} fully qualified class name.
     */
    String getListenerClassName();

    /**
     * <p>
     * Get the event sink method signature.
     * </p>
     *
     * @return {@link String} method signature.
     */
    String getMethodSignature();

    /**
     * <p>
     * Get the fully qualified name of the supported source class.
     * </p>
     * 
     * @return {@link String} fully qualified class name.
     */
    String getSourceClassName();

    /**
     * <p>
     * Determine whether this event sink is only notified of events if one or more conditions are met. Currently this
     * means that one or more of the following are true:<br/>
     * <ul>
     * <li>
     * The event sink has at least one <em>required</em> after-token applied to it.
     * </li>
     * <li>
     * The event sink has at least one <em>required</em> before-token applied to it. 
     * </li>
     * <li>
     * The event sink requires an attribute match.
     * </li>
     * </ul>
     * </p>
     * <p>
     * This method exist as a small optimization; if its return value is <code>false</code>, certain pieces of metadata
     * need not be consulted each time the event sink is notified of an event. 
     * </p>
     *
     * @return <code>boolean</code> <code>true</code> if the event sink is to be invoked conditionally.
     */
    boolean isConditional();

    /**
     * <p>
     * Determine whether this event sink contributes at least one ordering token. 
     * </p>
     *
     * @return <code>boolean</code> <code>true</code> if the event sink is a contributor.
     */
    boolean isContributor();

    /**
     * <p>
     * Determine whether this event sink is ordered with respect to the contributions of other event sinks.
     * </p>
     * 
     * @return <code>boolean</code> <code>true</code> if the event sink is ordered.
     */
    boolean isOrdered();
}
